/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.bopet.jocadv.gui;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

/**
 *
 * @author bocskapeter
 */
public class InputHandler implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener {

    // Relative mouse movement x direction for rotation
    private double dxr;
    // Relative mouse movement y direction for rotation
    private double dyr;
    // Relative mouse movement x direction for pan
    private double dxp;
    // Relative mouse movement y direction for pan
    private double dyp;
    // Mouse left click
    public boolean mouseLeftClick = false;
    // Mouse right click
    public boolean mouseRightClick = false;
    // Mouse middle click
    public boolean mouseMiddleClick = false;
    // Mouse x position
    public int mouseX = 0;
    // Mouse y position
    public int mouseY = 0;
    // Pan in x direction
    private double panx;
    // Pan in y direction
    private double pany;
    // Zoom increment
    private double zoomIncrement;
    // Zoom sensibility
    static private final double ZOOM_SENSIBILITY = 0.1;
    // Rotate sensibility
    static private final double ROTATE_SENSIBILITY = 0.1;
    // Parent class
    private final GLRenderer glRenderer;

    public InputHandler(GLRenderer glRenderer) {
        this.glRenderer = glRenderer;
    }

    public double getDxr() {
        return dxr;
    }

    public void setDxr(double dxr) {
        this.dxr = dxr;
    }

    public double getDyr() {
        return dyr;
    }

    public void setDyr(double dyr) {
        this.dyr = dyr;
    }

    @Override
    public void keyTyped(KeyEvent ke) {

    }

    @Override
    public void keyPressed(KeyEvent ke) {

    }

    @Override
    public void keyReleased(KeyEvent ke) {

    }

    @Override
    public void mouseClicked(MouseEvent me) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) {
            mouseLeftClick = true;            
        }
        if (e.getButton() == MouseEvent.BUTTON2) {
            mouseMiddleClick = true;
        }
        if (e.getButton() == MouseEvent.BUTTON3) {
            mouseRightClick = true;
        }
        mouseX = e.getX();
        mouseY = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        mouseLeftClick = false;
        mouseRightClick = false;
        mouseMiddleClick = false;
        dxr = 0;
        dyr = 0;
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // rotate scene
        if (mouseMiddleClick) {
            dyr = e.getX() - mouseX;
            dxr = e.getY() - mouseY;
            glRenderer.setrAngle(Math.sqrt(dxr * dxr + dyr * dyr) / glRenderer.getWidth() * 90 / ROTATE_SENSIBILITY);
        }
        // pan scene
        if (mouseRightClick) {
            dxp = (e.getX() - mouseX) * (glRenderer.getViewRight() - glRenderer.getViewLeft()) / glRenderer.getWidth();
            dyp = (e.getY() - mouseY) * (glRenderer.getViewTop() - glRenderer.getViewBottom()) / glRenderer.getHeight();
            glRenderer.setViewLeft(glRenderer.getViewLeft() - dxp);
            glRenderer.setViewRight(glRenderer.getViewRight() - dxp);
            glRenderer.setViewBottom(glRenderer.getViewBottom() + dyp);
            glRenderer.setViewTop(glRenderer.getViewTop() + dyp);

        }
        mouseX = e.getX();
        mouseY = e.getY();
    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        // center of the zoom
        mouseX = e.getX();
        mouseY = e.getY();

        // calculate zoom
        zoomIncrement = 1 + (e.getWheelRotation() * ZOOM_SENSIBILITY);

        // calculate panx
        panx = (glRenderer.getViewLeft() + (mouseX / (double) glRenderer.getWidth()) * (glRenderer.getViewRight() - glRenderer.getViewLeft())) - (glRenderer.getViewLeft() + (mouseX / (double) glRenderer.getWidth()) * (glRenderer.getViewRight() - glRenderer.getViewLeft())) * zoomIncrement;
        // calculate pany
        pany = (glRenderer.getViewBottom() + ((glRenderer.getHeight() - mouseY) / (double) glRenderer.getHeight()) * (glRenderer.getViewTop() - glRenderer.getViewBottom())) - (glRenderer.getViewBottom() + ((glRenderer.getHeight() - mouseY) / (double) glRenderer.getHeight()) * (glRenderer.getViewTop() - glRenderer.getViewBottom())) * zoomIncrement;

        // zoom
        glRenderer.setViewTop(glRenderer.getViewTop() * zoomIncrement);
        glRenderer.setViewBottom(glRenderer.getViewBottom() * zoomIncrement);
        glRenderer.setViewLeft(glRenderer.getViewLeft() * zoomIncrement);
        glRenderer.setViewRight(glRenderer.getViewRight() * zoomIncrement);

        // pan
        glRenderer.setViewTop(glRenderer.getViewTop() + pany);
        glRenderer.setViewBottom(glRenderer.getViewBottom() + pany);
        glRenderer.setViewLeft(glRenderer.getViewLeft() + panx);
        glRenderer.setViewRight(glRenderer.getViewRight() + panx);

    }   

}
